import pandas as pd
from sklearn.tree import DecisionTreeRegressor, plot_tree
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import numpy as np
from scipy.stats import norm

# 创建数据框
data = {
    'QK': [1, 2, 3, 4, 5, 6],
    'P1': [0.1,0.2,0.1,0.2,0.1,0.05],
    'B1': [4,4,4,4,4,4],
    'C1': [2,2,2,1,8,2],
    'P2': [0.1,0.2,0.1,0.2,0.2,0.05],
    'B2': [18,18,18,18,18,18],
    'C2': [3,3,3,1,1,3],
    'Pc':[0.1,0.2,0.1,0.2,0.1,0.05],
    'Cm': [6,6,6,6,6,6],
    'Cc': [3,3,3,2,2,3],
    'Bc': [56,56,56,56,56,56],
    'Cs': [6,6,30,30,10,10],
    'Ca': [5,5,5,5,5,40],
    'If1': [0,1,1,1,0,1],
    'If2': [0,0,1,1,1,0],
    'Ifc': [0,0,0,1,0,0],
    'Ifca': [0,0,0,0,0,1]
}
df = pd.DataFrame(data)

# 定义特征和目标变量
X = df[['QK','P1','B1','C1','P2','B2','C2','Pc','Cm','Cc','Bc','Cs','Ca','If1', 'If2','Ifc']]
y = df['Bc']-((df['B1']+df['C1']*df['If1']+df['B2']+df['C2']*df['If2']+df['Cm']+df['Cc']*df['Ifc'])+
              (df['Pc']*df['Ifc']*df['Ifca']*df['Ca']) + (1-df['Ifc'])*df['Pc']*df['Cs']
              )

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建决策树回归器并拟合数据
regr = DecisionTreeRegressor()
regr.fit(X_train, y_train)

# 预测测试集结果
y_pred = regr.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print("Mean Squared Error:", mse)

# 计算预测值与实际值之间的差异
errors = y_test - y_pred

# 计算平均值和标准差
mean_error = np.mean(errors)
std_dev_error = np.std(errors, ddof=1)

# 计算控制限
upper_control_limit = mean_error + 3 * std_dev_error / np.sqrt(len(errors))
lower_control_limit = mean_error - 3 * std_dev_error / np.sqrt(len(errors))

# 绘制控制图
plt.figure(figsize=(10, 5))
plt.plot(range(len(errors)), errors, 'bo', label='true')
plt.axhline(y=mean_error, color='r', linestyle='-', label='avg')
plt.axhline(y=upper_control_limit, color='g', linestyle='--', label='max')
plt.axhline(y=lower_control_limit, color='g', linestyle='--', label='min')
plt.xlabel('ID')
plt.ylabel('error')
plt.legend()
plt.show()


# 可视化决策树
plt.figure(figsize=(20, 10))
plot_tree(regr, filled=True, feature_names=X.columns, rounded=True)
plt.show()

# 设置字体为支持中文的字体
font = FontProperties(fname='/System/Library/Fonts/PingFang.ttc')
plt.rcParams['font.family'] = font.get_name()
